package user

import (
	"bytes"
	"encoding/base64"
	"github.com/gin-gonic/gin"
	"github.com/nfnt/resize"
	"image"
	"image/jpeg"
	_ "image/jpeg"
	"image/png"
	_ "image/png"
	"mime/multipart"
	"net/http"
	"one-wiki/commons"
	"one-wiki/logic"
	"path/filepath"
	"strconv"
	"strings"
)

func UserHandlersInit(engine *gin.Engine) {
	// 用户登录
	engine.POST("/user/login", userLogin)
	// 用户注册
	engine.POST("/user/register", userRegister)
	// 用户获取自身信息
	engine.GET("/user/self", userSelf)
	// 用户获取自身信息
	engine.POST("/user/self", userSelfUpdate)
	// 用户上传头像
	engine.POST("/user/avatar", uploadAvatar)
	// 用户获取所属组
	engine.GET("/user/group", userGroupList)
	// 用户退出指定的组
	engine.DELETE("/user/group/:id", exitGroup)
}

// uploadAvatar 用户上传头像
func uploadAvatar(c *gin.Context) {
	// 获取上传的图片
	file, err := c.FormFile("image")
	if err != nil {
		panic(err)
	}

	format := getUploadedImageFormat(file)

	// 读取上传的图片
	imageData, err := file.Open()
	if err != nil {
		panic(err)
	}
	defer imageData.Close()

	// 解码图片
	img, _, err := image.Decode(imageData)
	if err != nil {
		panic(err)
	}

	// 裁剪为正方形
	squareImg := cropToSquare(img)

	// 缩放为 64x64 大小
	resizedImg := resize.Resize(64, 64, squareImg, resize.Lanczos3)

	// 转换为 base64
	base64Data := encodeImageToBase64(resizedImg, format)

	c.String(http.StatusOK, base64Data)
}

func userLogin(c *gin.Context) {
	var requestParams commons.LoginRequest
	if err := c.ShouldBindJSON(&requestParams); err != nil {
		panic(commons.CustomClientError("参数错误"))
	}

	c.JSON(http.StatusOK, logic.Login(requestParams))
}

// 用户注册接口 UserRegister
func userRegister(c *gin.Context) {
	var form commons.UserRegisterRequest
	if err := c.ShouldBindJSON(&form); err != nil {
		panic(commons.CustomClientError("参数异常"))
	}
	c.JSON(http.StatusOK, logic.Register(form))
}

func userSelf(context *gin.Context) {
	// 获取Session 校验Session
	value, exists := context.Get(commons.KEY_SESSION)
	if !exists {
		panic(commons.UnAuthorizationErr)
	}
	localSession, ok := value.(commons.Session)
	if !ok {
		panic(commons.ServerError)
	}

	// 查询用户信息
	resp := logic.UserSelfInfo(localSession)

	// 响应
	context.JSON(http.StatusOK, resp)
}

// 用户更新个人信息
func userSelfUpdate(context *gin.Context) {
	// 获取Session 校验Session
	value, exists := context.Get(commons.KEY_SESSION)
	if !exists {
		panic(commons.UnAuthorizationErr)
	}
	localSession, ok := value.(commons.Session)
	if !ok {
		panic(commons.ServerError)
	}

	// 解析参数
	var param commons.UserSelfRequest
	if err := context.ShouldBindJSON(&param); err != nil {
		panic(commons.CustomClientError("参数异常"))
	}

	// 查询用户信息
	resp := logic.UserSelfUpdate(localSession, param)

	// 响应
	context.JSON(http.StatusOK, resp)
}

// UserGroupList 用户获取所属组列表接口
func userGroupList(context *gin.Context) {
	// 获取Session 校验Session
	value, exists := context.Get(commons.KEY_SESSION)
	if !exists {
		panic(commons.UnAuthorizationErr)
	}
	localSession, ok := value.(commons.Session)
	if !ok {
		panic(commons.ServerError)
	}

	context.JSON(http.StatusOK, logic.GetUserGroupList(localSession))
}

// 用户退出指定组接口 ExitGroup
func exitGroup(c *gin.Context) {
	// 获取Session 校验Session
	value, exists := c.Get(commons.KEY_SESSION)
	if !exists {
		panic(commons.UnAuthorizationErr)
	}
	localSession, ok := value.(commons.Session)
	if !ok {
		panic(commons.ServerError)
	}

	// 获取组 ID 参数
	groupID, err := strconv.ParseInt(c.Param("id"), 10, 64)
	if err != nil {
		panic(commons.CustomClientError("参数错误"))
	}

	logic.ExitGroup(localSession.UserID, groupID)

	c.JSON(http.StatusOK, commons.SuccessResponse)
}

// 裁剪图片为正方形（保留正中间部分）
func cropToSquare(img image.Image) image.Image {
	width := img.Bounds().Size().X
	height := img.Bounds().Size().Y

	size := width
	if width > height {
		size = height
	}

	x := (width - size) / 2
	y := (height - size) / 2

	rect := image.Rect(x, y, x+size, y+size)
	squareImg := img.(interface {
		SubImage(r image.Rectangle) image.Image
	}).SubImage(rect)

	return squareImg
}

// 将图片转换为 base64
func encodeImageToBase64(img image.Image, format string) string {
	output := new(bytes.Buffer)

	switch format {
	case "jpeg":
		err := jpeg.Encode(output, img, nil)
		if err != nil {
			panic(err)
		}
		return "data:image/jpeg;base64," + base64.StdEncoding.EncodeToString(output.Bytes())
	case "png":
		err := png.Encode(output, img)
		if err != nil {
			panic(err)
		}
		return "data:image/png;base64," + base64.StdEncoding.EncodeToString(output.Bytes())
	default:
		panic(commons.CustomServerError("未支持的格式"))
	}
}

// 获取图片的格式
func getUploadedImageFormat(file *multipart.FileHeader) string {
	filename := file.Filename
	extension := strings.TrimPrefix(filepath.Ext(filename), ".")
	switch extension {
	case "jpg", "jpeg":
		return "jpeg"
	case "png":
		return "png"
	default:
		panic(commons.CustomServerError("未支持的格式"))
	}
}
